/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package proyecto;

/**
 *
 * @author Luis Romero
 */
import java.util.logging.Level;
import java.util.logging.Logger;
import static proyecto.Constantes.*;

public class Reloj extends Thread {

    IF fetch;
    ID id;
    EX ex;
    Mem m;
    WB wb;
    
    final Object lock;

    int maxQuantum;
    int ticks;
    int acumulado;
    int numHilos;
    boolean hilos[];

    public Reloj(IF f,ID d,EX e, Mem me, WB w){
        fetch = f;
        id = d;
        ex = e;
        m = me;
        wb = w;
        acumulado=0;
        ticks = 4;
        lock = new Object();
        hilos = new boolean[5];
    }

    public void cuentaHilo(int hilo){
        hilos[hilo] = true;
    }

    public void setMaxQuantum(int m){
        this.maxQuantum = m;
    }

    public int getMaxQuantum(){
        return this.maxQuantum;
    }
    
    public int getCuenta(){
        int cuenta = 0;
        for(int i = 0; i < 5; i++){
            if(hilos[i])
                cuenta++;
        }
        return cuenta;
    }
    
    public void reiniciaHilos(){
        for(int i = 0; i < 5; i++)
            hilos[i] = false;
    }
    
    public void tick(){
        while(getNumHilos() > 0){
            while(getCuenta() < getNumHilos())
                parar();
                ticks++;
                reiniciaHilos();
        }
    }
    
    public int getTicks(){ return ticks; }
    
    public void run(){
        tick();
    }
    
    public void parar() {
        synchronized (lock) {
            try {
               // System.out.println("Parar IF");
                lock.wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(ID.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void seguir() {
        synchronized (lock) {
           // System.out.println("Seguir IF");
            lock.notify();
        }
    }
    
    public synchronized void DarSeñal(){
        acumulado++;
        if(acumulado == getNumHilos()){
            acumulado=0;
            fetch.seguir();
            id.seguir();
            ex.seguir();
            m.seguir();
            wb.seguir();
        }
    }

    public int getNumHilos(){
        int retorno=0;
        if(fetch.getState()!=Thread.State.TERMINATED){
            retorno++;
        }
        if(id.getState()!=Thread.State.TERMINATED){
            retorno++;
        }
        if(ex.getState()!=Thread.State.TERMINATED){
            retorno++;
        }
        if(m.getState()!=Thread.State.TERMINATED){
            retorno++;
        }
        if(wb.getState()!=Thread.State.TERMINATED){
            retorno++;
        }
        return retorno;
    }


}
